package com.mk.property.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mk.property.dto.ChargeDto;
import com.mk.property.pojo.Charge;
import com.mk.property.pojo.Room;
import com.mk.property.service.ChargeService;
import com.mk.property.service.RoomService;
import com.mk.property.mapper.RoomMapper;
import com.mk.property.vo.ChargeFormVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.time.LocalDate;
import java.time.Period;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author apple
 * @description 针对表【room(房屋表)】的数据库操作Service实现
 * @createDate 2022-12-21 16:16:34
 */
@Service
@Slf4j
public class RoomServiceImpl extends ServiceImpl<RoomMapper, Room> implements RoomService {
    //物业费单价
    @Value("${price.property-price}")
    private Double propertyPrice;

    //电梯费单价
    @Value("${price.elevator-price}")
    private Double elevatorPrice;

    //水费单价
    @Value("${price.water-price}")
    private Double waterPrice;

    //电费单价
    @Value("${price.electricity_price}")
    private Double electricityPrice;

    @Autowired
    ChargeService chargeService;

    /**
     * 获取月份数量
     *
     * @param chargeDto
     * @return
     */
    private Integer getMonths(ChargeDto chargeDto) {
        Date startDate = chargeDto.getStartDate();
        Date endDate = chargeDto.getEndDate();
        //首先把Date对象转换为Instant对象
        Instant startIns = startDate.toInstant();
        Instant endIns = endDate.toInstant();
        //然后把Instant对象转换为LocalDate对象
        LocalDate startMonth = startIns.atZone(ZoneId.of("Asia/Shanghai")).toLocalDate();
        LocalDate endMonth = endIns.atZone(ZoneId.of("Asia/Shanghai")).toLocalDate();
        Period period = Period.between(startMonth, endMonth);
        //数量
        return period.getMonths();
    }

    private List<Double> getPropertyAmountAndMoney(ChargeDto chargeDto, Integer months) {
        //求物业费
        String roomAddress = chargeDto.getRoomNumber();
        //这里我们需要知道房子的面积
        LambdaQueryWrapper<Room> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Room::getRoomNumber, roomAddress);
        Room room = this.getOne(lqw);
        double area = room.getArea();
        log.info("房子面积为{}", area);
        //别忘了乘上月份
        double propertyAmount = months * area;
        //金额
        double propertyMoney = propertyAmount * propertyPrice;
        List<Double> result = new ArrayList<>();
        result.add(propertyAmount);
        result.add(propertyMoney);
        return result;
    }

    private List<Double> getElevatorAmountAndMoney(ChargeDto chargeDto, Integer months) {
        String roomAddress = chargeDto.getRoomNumber();
        //首先求楼层高度 height
        //2期3单元25号楼5层1户
        int index1 = roomAddress.indexOf("楼") + 1;
        int index2 = roomAddress.indexOf("层");
        String height = roomAddress.substring(index1, index2);
        log.info("楼层高度为{}", height);
        double elevatorAmount = Double.parseDouble(height) * months;
        //金额
        double elevatorMoney = elevatorAmount * elevatorPrice;
        List<Double> result = new ArrayList<>();
        result.add(elevatorAmount);
        result.add(elevatorMoney);
        return result;
    }

    @Override
    public List<ChargeFormVO> getChargeInfo(ChargeDto chargeDto) {
        List<ChargeFormVO> list = new ArrayList<>();
        //求总共交几个月
        Integer months = getMonths(chargeDto);
        //求物业费
        List<Double> propertyAmountAndMoney = getPropertyAmountAndMoney(chargeDto, months);
        double propertyAmount = propertyAmountAndMoney.get(0);
        //金额
        double propertyMoney = propertyAmountAndMoney.get(1);
        list.add(getNewRow("1", "物业费", propertyAmount, propertyMoney));


        //电梯费
        List<Double> elevatorAmountAndMoney = getElevatorAmountAndMoney(chargeDto, months);
        //层高
        double elevatorAmount = elevatorAmountAndMoney.get(0);
        //金额
        double elevatorMoney = elevatorAmountAndMoney.get(1);
        list.add(getNewRow("2", "电梯费", elevatorAmount, elevatorMoney));

        //水费
        Double waterAmount = chargeDto.getWaterConsumption();
        //金额
        Double waterMoney = waterAmount * waterPrice;
        list.add(getNewRow("3", "水费", waterAmount, waterMoney));

        //电费
        Double electricityAmount = chargeDto.getPowerConsumption();
        //金额
        Double electricityMoney = electricityAmount * electricityPrice;
        list.add(getNewRow("4", "电费", electricityAmount, electricityMoney));

        //合计金额
        Double totalMoney = propertyMoney + elevatorMoney + waterMoney + electricityMoney;
        ChargeFormVO totalRow = new ChargeFormVO();
        totalRow.setMoney(String.format("%.2f", totalMoney));
        totalRow.setId("合计");
        list.add(totalRow);

        return list;
    }

    /**
     * 把前端的数据经过转化保存到数据库的表中
     * room
     * charge
     *
     * @param chargeDto
     */
    @Override
    @Transactional
    public void submitChargeOrder(ChargeDto chargeDto) {
        //首先操作charge表
        Charge charge = new Charge();
        charge.setRoomNumber(chargeDto.getRoomNumber());
        charge.setStartDate(chargeDto.getStartDate());
        charge.setEndDate(chargeDto.getEndDate());


        //业主编号
        LambdaQueryWrapper<Room> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Room::getRoomNumber, chargeDto.getRoomNumber());
        Room room = this.getOne(lqw);
        charge.setOwnerId(room.getOwnerId());

        //要交几个月
        Integer months = getMonths(chargeDto);
        //物业费金额
        List<Double> propertyAmountAndMoney = getPropertyAmountAndMoney(chargeDto, months);
        Double propertyMoney = propertyAmountAndMoney.get(1);
        charge.setPropertyMoney(propertyMoney);

        //电梯费金额
        List<Double> elevatorAmountAndMoney = getElevatorAmountAndMoney(chargeDto, months);
        Double elevatorMoney = elevatorAmountAndMoney.get(1);
        charge.setElevatorMoney(elevatorMoney);

        //水费金额
        Double waterAmount = chargeDto.getWaterConsumption();
        Double waterMoney = waterAmount * waterPrice;
        charge.setWaterMoney(waterMoney);

        //电费金额
        Double electricityAmount = chargeDto.getPowerConsumption();
        Double electricityMoney = electricityAmount * electricityPrice;
        charge.setElectricMoney(electricityMoney);

        //总金额
        Double totalMoney = propertyMoney + elevatorMoney + waterMoney + electricityMoney;
        charge.setTotalMoney(totalMoney);

        //执行收费操作的员工号
        charge.setEmployeeId(Long.valueOf(chargeDto.getEmployeeId()));

        //收费日期
        charge.setChargeDate(new Date());

        //把charge保存到数据库中
        chargeService.save(charge);

        //再操作room表
        room.setValidDate(chargeDto.getEndDate());
        this.updateById(room);
    }

    //封装收费单的每一行
    public ChargeFormVO getNewRow(String id, String chargeType, Double amount, Double money) {
        ChargeFormVO chargeFormVO = new ChargeFormVO();
        chargeFormVO.setId(id);
        chargeFormVO.setChargeType(chargeType);
        chargeFormVO.setAmount(String.format("%.2f", amount));
        chargeFormVO.setMoney(String.format("%.2f", money));
        return chargeFormVO;
    }
}




